/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DaveSexton.DocProject.Engine;
using System.IO;

namespace DaveSexton.DocProject.Sandcastle
{
	internal sealed class HtmlHelpWorkshopStep : ExternalProcessBuildStep<SandcastleBuildEngine>
	{
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1802:UseLiteralsWhereAppropriate")]
		public static readonly string DefaultName = "Compile Help 1.x";

		public override string Name
		{
			get
			{
				return DefaultName;
			}
		}

		public HtmlHelpWorkshopStep(SandcastleBuildEngine engine, SandcastleSettings settings, string workshopProject)
			: base(engine, false, settings.HtmlHelpWorkshop, "\"" + workshopProject + "\"")
		{
			IncludeInPartialBuild = true;
			RunInBackground = true;
		}

		protected override int ExecuteExternalProcess(BuildContext context)
		{
			string outputDir = Engine.Settings.TargetDirectory;
			string outputFile = Path.Combine(outputDir, Engine.Settings.CompiledHelp1xFileName);

			int value = Compile(context, outputDir, outputFile);

			if (value == 0)  // success
			{
				string target = Engine.Settings.CompiledHelp1xFile;

				if (!string.Equals(outputFile, target, StringComparison.OrdinalIgnoreCase))
				{
					string targetDir = Path.GetDirectoryName(target);

					if (!Directory.Exists(targetDir))
						Directory.CreateDirectory(targetDir);

					// do not use File.Move since it throws an exception if the file already exists
					File.Copy(outputFile, target, true);
					File.Delete(outputFile);
				}
			}

			return value;
		}

		private int Compile(BuildContext context, string outputDir, string outputFile)
		{
			string dir = context.CurrentDirectory;
			context.CurrentDirectory = outputDir;

			try
			{
				int code = base.ExecuteExternalProcess(context);

				// Html Help Workshop compiler seems to always return an exit code of 1 for success.
				// If the output file is missing then assume that an error occurred; otherwise, 
				// check the error code.
				if (!File.Exists(outputFile))
					return (code != 0) ? code : 2;		// error
				else if (code != 1)
					// It's assumed that an exit code other than 1 may be returned in the case of an actual error.
					// In testing, zero was returned in an error situation.  When zero is returned by the compiler, 
					// 1 is returned by DocProject since 1 can be identified as DocProject-generated.
					return (code == 0) ? 1 : code;
				else
					return 0;		// success
			}
			finally
			{
				context.CurrentDirectory = dir;
			}
		}
	}
}
